#include "gpio.h"
#include "main.h"
#include "usb_device.h"
#include "usb_midi.h"
#include "drv_pwm.h"
#include "app_midi.h"
#include "app_misc.h"
#include "app_msg.h"
#include "app_sys.h"
#include "app_pwr.h"
#include "app_msg.h"
#include "app_flash_config.h"

/****
 * Pedal
 */
#define DZQ_RUOY_Pin GPIO_PIN_13
#define DZQ_RUOY_GPIO_Port GPIOB
#define DZQ_YANY_Pin GPIO_PIN_12
#define DZQ_YANY_GPIO_Port GPIOB

static 

/*********
 * Taban
 */

#define SUSTAIN_PEDAL_GPIO_Port DZQ_YANY_GPIO_Port
#define SUSTAIN_PEDAL_Pin DZQ_YANY_Pin
#define SOFT_PEDAL_GPIO_Port DZQ_RUOY_GPIO_Port
#define SOFT_PEDAL_Pin DZQ_RUOY_Pin

#define YANY 0
#define RUOY 1

// 占空比上下限数组，分别存储 [最小占空比, 最大占空比]
const uint8_t duty_cycle_limits[2][2] = {
    {20, 80}, // 第一个踏板的占空比上下限
    {20, 80}  // 第二个踏板的占空比上下限
};

// 踏板配置数组（初始化）
PedalControl taban_pedals[2] = {
    {   // 延音踏板（YANY）
        .state = TABAN_STATE_OFF,
        .pwm_channel = TIM_CHANNEL_1,
        .hit_duration = APP_PEDAL_HIT_DURATION_INIT,
        .hit_period = APP_PEDAL_HIT_PERIOD_INIT,
        .hit_duty_cycle = APP_PEDAL_HIT_DUTY_CYCLE_INIT,

        .return_duration = APP_PEDAL_RETURN_DURATION_INIT,
        .return_period = APP_PEDAL_RETURN_PERIOD_INIT,
        .return_duty_cycle = APP_PEDAL_RETURN_DUTY_CYCLE_INIT,

        .hover_duration = APP_PEDAL_HOVER_DURATION_INIT,
        .hover_period = APP_PEDAL_HOVER_PERIOD_INIT,
        .hover_duty_cycle = APP_PEDAL_HOVER_DUTY_CYCLE_INIT
    },
    {   // 弱音踏板（RUOY）
        .state = TABAN_STATE_OFF,
        .pwm_channel = TIM_CHANNEL_2,
        .hit_duration = APP_PEDAL_HIT_DURATION_INIT,
        .hit_period = APP_PEDAL_HIT_PERIOD_INIT,
        .hit_duty_cycle = APP_PEDAL_HIT_DUTY_CYCLE_INIT,

        .return_duration = APP_PEDAL_RETURN_DURATION_INIT,
        .return_period = APP_PEDAL_RETURN_PERIOD_INIT,
        .return_duty_cycle = APP_PEDAL_RETURN_DUTY_CYCLE_INIT,

        .hover_duration = APP_PEDAL_HOVER_DURATION_INIT,
        .hover_period = APP_PEDAL_HOVER_PERIOD_INIT,
        .hover_duty_cycle = APP_PEDAL_HOVER_DUTY_CYCLE_INIT
    }
};

// // 踏板配置数组
// PedalControl taban_pedals[2] = {
//     {   // 延音踏板（YANY）
//         .state = TABAN_STATE_OFF,
//         .pwm_channel = TIM_CHANNEL_1,
//         .hit_duration = 20,     // 打击阶段持续时间（单位：ms）
//         .hit_period = 20,       // 打击阶段 PWM 周期（单位：ms）
//         .hit_duty_cycle = 70,   // 打击阶段占空比

//         .return_duration = 40, // 回击阶段持续时间（单位：ms）
//         .return_period = 20,    // 回击阶段 PWM 周期（单位：ms）
//         .return_duty_cycle = 50,// 回击阶段占空比

//         .hover_duration = 0,    // 悬停阶段持续时间为 0 表示持续
//         .hover_period = 20,     // 悬停阶段 PWM 周期（单位：ms）
//         .hover_duty_cycle = 35  // 悬停阶段占空比
//     },
//     {   // 弱音踏板（RUOY）
//         .state = TABAN_STATE_OFF,
//         .pwm_channel = TIM_CHANNEL_2,
//         .hit_duration = 20,     // 打击阶段持续时间（单位：ms）
//         .hit_period = 20,       // 打击阶段 PWM 周期（单位：ms）
//         .hit_duty_cycle = 70,   // 打击阶段占空比

//         .return_duration = 40,  // 回击阶段持续时间（单位：ms）
//         .return_period = 20,    // 回击阶段 PWM 周期（单位：ms）
//         .return_duty_cycle = 50,// 回击阶段占空比

//         .hover_duration = 0,    // 悬停阶段持续时间为 0 表示持续
//         .hover_period = 20,     // 悬停阶段 PWM 周期（单位：ms）
//         .hover_duty_cycle = 35  // 悬停阶段占空比
//     }
// };


void app_taban_pwm_handle_state(uint8_t pedal_channel)
{
    // 检查 PWM 通道号是否合法
    if (pedal_channel >= 2)
    {
        return;
    }

    // 获取对应的踏板配置
    PedalControl *pedal = &taban_pedals[pedal_channel];

    // 处理踏板状态
    switch (pedal->state)
    {
    case TABAN_STATE_OFF: // 关闭状态
        drv_pwm_stop(pedal->pwm_channel); // 停止 PWM
        break;

    case TABAN_STATE_HIT: // 打击阶段
        drv_pwm_start(
            pedal->pwm_channel,
            pedal->hit_duty_cycle,    // 占空比
            pedal->hit_duration     // 持续时间   
        );
        break;

    case TABAN_STATE_RETURN: // 回击阶段
        drv_pwm_start(
            pedal->pwm_channel,
            pedal->return_duty_cycle, // 占空比
            pedal->return_duration  // 持续时间
        );
        break;

    case TABAN_STATE_HOVER: // 悬停阶段
        drv_pwm_start(
            pedal->pwm_channel,
            pedal->hover_duty_cycle,  // 占空比
            pedal->hover_duration   // 持续时间
        );
        break;

    default:
        // 未知状态，不做处理
        break;
    }
}


void app_taban_switch_state(uint8_t pedal_channel)
{
    if(pedal_channel >= 2)
    {
        return;
    }

    // 获取对应的踏板配置
    PedalControl *pedal = &taban_pedals[pedal_channel];
    TABAN_State current_state = pedal->state; // 记录初始状态
 
    switch (current_state)
    {
    case TABAN_STATE_OFF:
        {
            pedal->state=TABAN_STATE_HIT;
            app_taban_pwm_handle_state(pedal_channel);
        }
        break;
    case TABAN_STATE_HIT:
        {   
            pedal->state = TABAN_STATE_RETURN;
            app_taban_pwm_handle_state(pedal_channel);
        }
        break;
    case TABAN_STATE_RETURN:
        {
            pedal->state = TABAN_STATE_HOVER;
            app_taban_pwm_handle_state(pedal_channel);
        }
        break;
    case TABAN_STATE_HOVER:
        {
            pedal->state = TABAN_STATE_OFF;
            app_taban_pwm_handle_state(pedal_channel);
        }
        break; 
    default:
        break;
    }      
}


/*****
 * MIDI
 */

static uint8_t map_value_to_duty_cycle(uint8_t value, uint8_t min_duty, uint8_t max_duty)
{
    if (value > 0x7F) {
        value = 0x7F; // 限制最大值
    }
    return min_duty + (value * (max_duty - min_duty) / 0x7F);
}

void app_midi_handle_msg(uint8_t midi_msg[3])
{
    PedalControl *yany_pedal = &taban_pedals[0];
    PedalControl *ruoy_pedal = &taban_pedals[1];

    // 检查消息是否是 Control Change (CC) 消息
    if ((midi_msg[0] & 0xF0) == 0xB0) // B0 表示 Control Change
    {
        uint8_t controller = midi_msg[1];  // 控制器编号
        uint8_t value = midi_msg[2];       // 控制器值 (0x00 到 0x7F)

        switch (controller)
        {
        case 0x03:
            {
                if(value == 0x00)
                {
                    if(!is_power_off())
                    {
                        app_power_off();    //关机
                    }
                }
            }
            break;
        case 0x40: // 0x40 表示延音踏板
            {
                if (value == 0x00) // 关闭延音踏板
                {
                    drv_pwm_stop(yany_pedal->pwm_channel); // 停止 PWM 通道 0（假设延音踏板对应 PWM 通道 0）
                    yany_pedal->state = TABAN_STATE_OFF;

                    HAL_GPIO_WritePin(DZQ_YANY_GPIO_Port, DZQ_YANY_Pin, GPIO_PIN_RESET); // 输出低电平
                }
                else // 开启延音踏板
                {
                    uint8_t duty_cycle = map_value_to_duty_cycle(value, duty_cycle_limits[0][0], duty_cycle_limits[0][1]); // MIDI 的 1-7F 转换为占空比
                    yany_pedal->return_duration = 40;
                    yany_pedal->return_duty_cycle = duty_cycle;
                    yany_pedal->state = TABAN_STATE_OFF;
                    drv_pwm_stop(yany_pedal->pwm_channel);
                    app_taban_switch_state(YANY);

                    HAL_GPIO_WritePin(DZQ_YANY_GPIO_Port, DZQ_YANY_Pin, GPIO_PIN_SET);   // 输出高电平
                }
            }
            break;
        case 0x43: // 0x43 表示弱音踏板
            {
                if (value == 0x00) // 关闭弱音踏板
                {
                    drv_pwm_stop(ruoy_pedal->pwm_channel); // 停止 PWM 通道 1（假设弱音踏板对应 PWM 通道 1）
                    ruoy_pedal->state = TABAN_STATE_OFF;
                    HAL_GPIO_WritePin(DZQ_RUOY_GPIO_Port, DZQ_RUOY_Pin, GPIO_PIN_RESET); // 输出低电平
                }
                else // 开启弱音踏板
                {
                    // MIDI 的 1-7F 转换为占空比
                    uint8_t duty_cycle = map_value_to_duty_cycle(value, duty_cycle_limits[0][0], duty_cycle_limits[0][1]); // MIDI 的 1-7F 转换为占空比
                    ruoy_pedal->return_duration = 40;
                    ruoy_pedal->return_duty_cycle = duty_cycle;
                    ruoy_pedal->state = TABAN_STATE_OFF;
                    drv_pwm_stop(ruoy_pedal->pwm_channel);
                    app_taban_switch_state(RUOY);
    
                    HAL_GPIO_WritePin(DZQ_RUOY_GPIO_Port, DZQ_RUOY_Pin, GPIO_PIN_SET);   // 输出高电平
                }
            }
            break;
        default:
            break;
        }
    }
}

void app_midi_handle_cmd(uint8_t *data, uint16_t size)
{
    for(uint16_t i=0; i<size; i++) 
    {
        // 发现状态字节（最高位为1）
        if(data[i] & 0x80) 
        {
            // 基础格式验证：状态字节范围为常规MIDI消息
            uint8_t status = data[i] & 0xF0;
            if(status >= 0x80 && status <= 0xE0) 
            {
                // 确定需要的数据字节数量
                uint8_t data_bytes = (status == 0xC0 || status == 0xD0) ? 1 : 2;
                
                // 检查数据完整性
                if(i + data_bytes >= size) break;
                
                // 验证数据字节有效性（最高位为0）
                if((data[i+1] & 0x80) == 0 && 
                   (data_bytes ==1 || (data[i+2] & 0x80) == 0)) 
                {
                    // 发现有效MIDI数据时执行开机
                    if(!is_power_on())
                    {
                        app_power_on();
                    }
                    return; // 发现有效格式即退出
                }
            }
        }
    }
}

// void app_midi_handle_cmd(uint8_t *data, uint16_t size)
// {
//     for (uint16_t i = 0; i < size; i += 1)
//     {
//         if (i + 2 < size)
//         {


            // if ((data[i] & 0xF0) == 0xB0) 
            // {
            //     if(data[i+1] == 0x03)   //开关机
            //     {
            //         if(data[i+2] == 0x7F)   
            //         {
            //             if(pwr_state!=PWR_ON)
            //             {
            //                 app_switch_pwr();
            //             }    
            //         }
            //         else if (data[i+2] == 0x00)
            //         {
            //             if(pwr_state!=PWR_OFF)
            //             {
            //                 app_switch_pwr();
            //             }   
            //         }
            //     }
            //     else if(data[i+1] == 0x0E)  //力度设定模式 进/出
            //     {
            //         if(data[i+2] == 0x7F)   
            //         {
            //             //进入
            //         }
            //         else if (data[i+2] == 0x00)
            //         {
            //             //退出
            //         }
            //     }
            // }
//         }
//     }
// }


void app_handle_usb_midi_data(uint8_t *data, uint16_t len)
{
    system_status.is_communicating = 1;  // 添加通信标记
#if (APP_USB_MIDI_DATA_DECODE == 1)
    APP_LOG_TIMESTAMP_PRINT();
    uint8_t useful_data[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
    uint8_t data_length = 0; // 有效数据的长度
    uint8_t i;

    // 初始化 useful_data 缓冲区
    memset(useful_data, 0, sizeof(useful_data));

    // 遍历每 4 字节一组的数据
    for (i = 0; i < len; i += 4) {
        // 检查剩余字节是否不足 4 字节，避免越界
        if (i + 4 > len) {
            break;
        }

        // 检查当前组的第一个字节是否不为 0
        if (data[i] != 0) {
            // 添加第 2、3、4 字节到 useful_data
            useful_data[data_length++] = data[i + 1];
            useful_data[data_length++] = data[i + 2];
            useful_data[data_length++] = data[i + 3];

            // 检查有效数据长度是否超出缓冲区大小，避免越界
            if (data_length >= sizeof(useful_data)) {
                break;
            }
        }
    }
    if(pwr_state == PWR_ON)
    {
        app_msg_enqueue(&uart_rx_queue, 
                        SRC_USB,          // 使用预定义的端口/类型值
                        useful_data, 
                        data_length);
    }
    else
    {
        app_midi_handle_cmd(useful_data, data_length);
    }
#else
    if(pwr_state == PWR_ON)
    {
        app_msg_enqueue(&uart_rx_queue, 
                        SRC_USB,          // 使用预定义的端口/类型值
                        data, 
                        len);
    }
    else
    {
        app_midi_handle_cmd(data, len);
    }
#endif
}

void app_msg_process_midi_data(uint8_t *data, uint16_t size)
{
#if (APP_ENABLE_AUTO_POWER_DWON == 1)
    extern uint32_t TIM_auto_power_down_count;
    TIM_auto_power_down_count = 0;
#endif

    for (uint16_t i = 0; i < size; i += 3)
    {
        if (i + 2 < size)
        {
             /* 关键修改点：直接发送3字节原始数据 */
             app_msg_enqueue(&midi_queue,        
                             T_MSG_MIDI_TYPE,   
                             &data[i],           
                             3);                 
        }
    }
}

void app_taban_stop_all(void)
{
    // 只关闭踏板，不影响电源状态
    drv_pwm_stop(TIM_CHANNEL_1);
    drv_pwm_stop(TIM_CHANNEL_2);
    HAL_GPIO_WritePin(DZQ_YANY_GPIO_Port, DZQ_YANY_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(DZQ_RUOY_GPIO_Port, DZQ_RUOY_Pin, GPIO_PIN_RESET);
    
    // 更新踏板状态
    taban_pedals[YANY].state = TABAN_STATE_OFF;
    taban_pedals[RUOY].state = TABAN_STATE_OFF;
}

void app_midi_handle_msg_force_setting(uint8_t midi_msg[3])
{
    if ((midi_msg[0] & 0xF0) == 0xB0) // Control Change消息
    {
        uint8_t controller = midi_msg[1];
        uint8_t value = midi_msg[2]; // 力度设定值(毫秒)
        
        // 限制范围在0-127ms
        if (value > 127) value = 127;
        
        if(value > 0)
        {
            switch (controller)
            {
            case 0x40: // B0 40 xx: 设置延音踏板打击时间为xx毫秒
                taban_pedals[YANY].hit_duration = value;
                break;
            case 0x43: // B0 43 xx: 设置弱音踏板打击时间为xx毫秒
                taban_pedals[RUOY].hit_duration = value;
                break;
            default:
                // 在力度设定模式下，忽略其他控制器指令
                break;
            }
        } 
    }
    app_midi_handle_msg(midi_msg); // 继续处理踏板开关等指令
    
}

uint8_t app_midi_flash_save_solenoid_durations()
{
    return app_flash_set_solenoid_durations(taban_pedals[YANY].hit_duration, taban_pedals[RUOY].hit_duration);
}

void app_taban_apply_flash_params(void)
{
    // 新增：从Flash加载电磁铁参数
    uint8_t yany_duration, ruoy_duration;
    app_flash_get_solenoid_durations(&yany_duration, &ruoy_duration);
    
    // 应用到踏板配置
    taban_pedals[YANY].hit_duration = yany_duration;
    taban_pedals[RUOY].hit_duration = ruoy_duration;
}
